#include <Arduino.h>
// #include <USBSerial.h>
#include <ArduinoJson.h>

#define PIN_IR PA1
#define PIN_LED PC13
#define LED_ON LOW

const char *VERSION = "0.1.0";
const char *CMD_GET_INFO = "sys_info";

uint32_t led_tick_count = 0;
uint32_t bightness = 100;
const uint32_t max_bightness = 256;
const uint32_t led_hz = 60;
const uint32_t led_interval_ms = 2000;
const uint32_t led_half_interval_ms = led_interval_ms >> 1;
const uint32_t led_quarter_interval_ms = led_interval_ms >> 2;
const uint32_t led_middle_ms = (led_interval_ms - led_quarter_interval_ms) >> 1;

uint32_t last_micros = 0;

HardwareTimer timer(TIM1);

void getSysInfo()
{
    JsonDocument doc;
    doc["type"] = CMD_GET_INFO;
    doc["board"] = BOARD_NAME;
    doc["cpu"] = F_CPU / 1000000; // MHz
    doc["version"] = VERSION;
    serializeJson(doc, SerialUSB);
    SerialUSB.println();
}

void emitIRElapsed()
{
    uint32_t now = micros();
    uint32_t elapsed = now < last_micros ? ~0U - last_micros + now : now - last_micros;
    last_micros = now;
    int high = digitalRead(PIN_IR);
    JsonDocument doc;
    doc["type"] = high ? F("high") : F("low");
    doc["elapsed"] = elapsed;
    serializeJson(doc, SerialUSB);
    SerialUSB.println();
}

void ledInterruptHandler()
{
    // 呼吸灯
    bightness = millis() % led_interval_ms;
    if (bightness < led_quarter_interval_ms)
    {
        // digitalWrite(PIN_LED, !LED_ON);
        return;
    }
    bightness -= led_quarter_interval_ms;
    if (bightness > led_middle_ms)
    {
        bightness = led_interval_ms - led_quarter_interval_ms - bightness;
    }
    bightness >>= 3; // 亮度除以8
    // if (millis() % led_interval_ms > led_half_interval_ms)
    // {
    //     digitalWrite(PIN_LED, !LED_ON);
    //     return;
    // }
    // PWM
    led_tick_count < bightness ? digitalWrite(PIN_LED, LED_ON) : digitalWrite(PIN_LED, !LED_ON);
    if (led_tick_count >= max_bightness)
    {
        led_tick_count = 0;
        return;
    }
    led_tick_count++;
}

void setupLED()
{
    pinMode(PIN_LED, OUTPUT); // 使用PC13作为PWM输出
    digitalWrite(PIN_LED, !LED_ON);
    // timer.setOverflow(5, MICROSEC_FORMAT);
    timer.setOverflow(max_bightness * led_hz, HERTZ_FORMAT);
    timer.attachInterrupt(ledInterruptHandler); // 绑定中断回调
    timer.resume();                             // 启动定时器
}

void setup()
{
    setupLED();
    SerialUSB.begin();
    // setupIR
    pinMode(PIN_IR, INPUT_PULLUP);
    attachInterrupt(PIN_IR, emitIRElapsed, CHANGE);
}

void loop()
{
    // 循环处理串口收到的命令
    JsonDocument doc;
    while (SerialUSB.available() > 0)
    {
        DeserializationError error = deserializeJson(doc, SerialUSB);
        if (error)
        {
            SerialUSB.print(F("deserializeJson() failed: "));
            SerialUSB.println(error.c_str());
            return;
        }
        const char *cmd = doc["cmd"];
        if (strcmp(cmd, CMD_GET_INFO) == 0)
        {
            getSysInfo();
        }
    }
}
